feat(map): add place/address geocoder search to the map view - #353
Open
jirhiker wants to merge 2 commits into
Open
feat(map): add place/address geocoder search to the map view#353jirhiker wants to merge 2 commits into
jirhiker wants to merge 2 commits into
Conversation
Adds a debounced search box to the top-left panel stack on the map view. Selecting a result fits the map to the result's bounding box (or eases to its center) and drops a marker; results are biased toward the current viewport center. Geocoding goes to Photon, komoot's OpenStreetMap-backed service. Photon needs no account or token, which keeps the map free of API keys the way basemaps.ts already does, and unlike Nominatim its usage policy permits search-as-you-type. Photon returns address components rather than a formatted label and reports `extent` as [minLon, maxLat, maxLon, minLat], so utils/geocode.ts composes the display label and reorders the box into the [west, south, east, north] order fitBounds expects. Results are filtered to the US client side, since Photon has no country parameter. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
jirhiker
force-pushed
the
claude/geocoder-map-view-632abf
branch
from
August 21, 2026 21:10
f54981a to
d0ed57f
Compare
Preview DeploymentPreview URL: https://preview-claude-geocoder-map-view-632abf-auejgdbofq-uc.a.run.app Note: This preview uses the staging API endpoints. |
A query like "socorro" matches both the city and the county relation, and both compose to "Socorro, New Mexico" — two identical rows in the dropdown that fly to different extents. Where a label repeats, Photon's own type classification is now appended to each of the colliding rows. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Preview DeploymentPreview URL: https://preview-claude-geocoder-map-view-632abf-auejgdbofq-uc.a.run.app Note: This preview uses the staging API endpoints. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
Adds a geocoder (place / address / ZIP search) to the map view.
src/utils/geocode.ts— forward geocoding against Photon, komoot's OpenStreetMap-backed search service. Photon returns address components rather than a formatted string, and reportsextentas[minLon, maxLat, maxLon, minLat], so this module composes the display label and reorders the box into the[west, south, east, north]orderfitBoundsexpects. US filtering is client-side because Photon has no country parameter.src/components/MapGeocoderSearch.tsx— MUI search box: 300 ms debounce, 3-char minimum, react-query cache (5 min), result dropdown, loading spinner, clear button, Enter selects the first result, Esc clears. Credits OpenStreetMap in the dropdown footer, per ODbL.src/pages/ocotillo/map/list.tsx— new panel at the top of the existing top-left panel stack (Base Maps and Layers shift down by its measured height). Selecting a result fits the map to the result bbox (maxZoom 14) or eases to its center (zoom >= 13), drops a marker, clears any open popup, and captures amap_geocoder_result_selectedevent. Results are biased toward the current viewport center.Why Photon
Photon needs no account or API token, which keeps this consistent with
src/basemaps.ts— the MapLibre migration deliberately made every tile and data source key-free, and a geocoder with a token would have reintroduced exactly what that migration removed. Photon is also explicitly built for search-as-you-type, unlike Nominatim, whose usage policy forbids autocomplete.The trade-off:
photon.komoot.iois a community instance with no SLA or documented rate limit. The debounce and 3-char minimum keep request volume modest; if it ever becomes load-bearing, self-hosting Photon is the escape hatch.Note on history
This branch was originally cut from
productionand first implemented the search against the Mapbox Places API — that was written before I saw that #336 had already landed the MapLibre migration onstaging, removingsettings.mapboxTokenand deleting the unusedGeocoderControl.jsxwrapper. The branch is now rebased ontoorigin/stagingas a single commit, per AGENTS.md, and the geocoder is Photon-based. Nothing Mapbox-related remains in the diff.Testing
src/test/utils/geocode.test.ts— 4 unit tests: label composition, extent reordering, duplicate-component dedup, and rejection of non-US / coordinate-less / bad input. Passing.npm run typecheck— clean.noExplicitAnywarnings inmap/list.tsxare pre-existing and unchanged in count.vitest runcould not be trusted locally: this worktree has no installednode_modules, so the contract tests fail on the absent Prism mock server and three suites fail to resolve@mui/icons-materialfrom the parent checkout. CI is authoritative for those.🤖 Generated with Claude Code